package com.koron.tool.frame;

import com.koron.tool.Constant;
import com.koron.tool.MainFrame;
import com.koron.tool.constant.SavedTableSetting;
import com.koron.tool.dialog.OneKeyTableSqlBeanDialog;
import com.koron.tool.entity.Column;
import com.koron.tool.entity.ForeignKey;
import com.koron.tool.entity.Table;
import com.koron.tool.util.SerializeUtil;
import com.koron.util.StringUtils;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.sql.*;
import java.util.*;

/**
 * 由数据库表生成相应的bean,searchbean,viewbean,action,mapper,mybatis xml
 *
 * @author swan
 */
public class OneKeyTableSqlBeanAction extends AbstractAction {
    /**
     * serialVersionUID:TODO（用一句话描述这个变量表示什么）
     *
     * @since Ver 1.1
     */

    private static final long serialVersionUID = 2217134062763102578L;
    private MainFrame frame;
    private ResourceBundle resourceBuddle = null;

    public OneKeyTableSqlBeanAction(MainFrame frame) {
        this.frame = frame;
        resourceBuddle = ResourceBundle.getBundle(MainFrame.RESOURCEBUDDLE, frame.getLocale());
        putValue(NAME, "表名生成BEAN");
        putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_MASK + InputEvent.ALT_MASK));
    }

    @Override
    public void actionPerformed(ActionEvent e) {

        String tableName = JOptionPane.showInputDialog(frame, "请输入表名");
        if (StringUtils.isEmpty(tableName)) {
            return;
        }
        String str = "select * from " + tableName;
        if (str != null && !str.equals("")) {
            if (str.indexOf("where") == -1) {
                str += " where 1=2";
            } else {
                str += " and 1=2";
            }
            Connection conn = null;
            try {

                conn = MainFrame.getConnection(MainFrame.config.get(Constant.DATABASE_ALIAS));


                //获取所有的列
//				DatabaseMetaData databaseMetaData = conn.getMetaData();
//				String catalog = conn.getCatalog();
//				ResultSet columnsResultSet = databaseMetaData.getColumns(catalog,"%",tableName,"%");
//				int columnCount = columnsResultSet.getRow();
//				String[][] fields = new String[columnCount][7];
//				int i = 0;
//				while(columnsResultSet.next()){
//					String columnName = columnsResultSet.getString("COLUMN_NAME");
//					int type = columnsResultSet.getInt("DATA_TYPE");
//					fields[i][0] = "private";
//					//int type = metaData.getColumnType(i + 1);
//					switch (type) {
//						case Types.INTEGER:
//						case Types.SMALLINT:
//						case Types.TINYINT:
//							fields[i][1] = "Integer";
//							break;
//						case Types.BIT:
//						case Types.BOOLEAN:
//							fields[i][1] = "Boolean";
//							break;
//						case Types.FLOAT:
//						case Types.REAL:
//							fields[i][1] = "Float";
//							break;
//						case Types.DOUBLE:
//							fields[i][1] = "Double";
//							break;
//						case Types.DATE:
//						case Types.TIMESTAMP:
//							fields[i][1] = "Timestamp";
//							break;
//						case Types.DECIMAL:
//							fields[i][1]="BigDecimal";
//							break;
//						default:
//							fields[i][1] = "String";
//							break;
//					}
//				//	String columnName = metaData.getColumnLabel(i + 1);
//					fields[i][2] = columnName;
//
//					//对列名进行驼峰处理，转变成为属性名称
//
//					fields[i][3] = StringUtils.convertColNameToHumpStyle(columnName);
//
//
//					fields[i][4] = columnsResultSet.getString("REMARKS");
////					ResultSet rs2 = conn.getMetaData().getColumns(null, null, metaData.getTableName(i + 1),
////							metaData.getColumnName(i + 1));
////					if (rs2.next()) {
////						String tmp = rs2.getString("REMARKS");
////						if (tmp != null)
////							fields[i][4] = tmp;
////					}
////
////					rs2.close();
//
//					if("YES".equals(columnsResultSet.getString("IS_AUTOINCREMENT"))){
//						fields[i][5]="Y";
//					}
//					else{
//						fields[i][5]="N";
//					}
//
//
//					fields[i][6]="N";
//
//				}


                Table table = new Table();
                table.setTableName(tableName);
                ResultSet rs = conn.createStatement().executeQuery(str);
                ResultSetMetaData metaData = rs.getMetaData();
                //第一个字段存放修饰符 第二个字段存放类型声明,第三个字段存放字段名称,第四个字段存放属性名称,第五个存放备注，第六个存放是否主键，第七个字段存放是否自增
                int columnCount = metaData.getColumnCount();
                //	String[][] fields = new String[metaData.getColumnCount()][7];
                //获取表名
                //String tableName = metaData.getTableName(1);
                for (int i = 0; i < columnCount; i++) {
                    Column column = new Column();
                    column.setDecorator("private");

                    //fields[i][0] = "private";
                    int type = metaData.getColumnType(i + 1);
                    switch (type) {
                        case Types.INTEGER:
                        case Types.SMALLINT:
                        case Types.TINYINT:
                            column.setType("Integer");
                            //fields[i][1] = "Integer";
                            break;
                        case Types.BIT:
                        case Types.BOOLEAN:
                            column.setType("Boolean");
                            //fields[i][1] = "Boolean";
                            break;
                        case Types.FLOAT:
                        case Types.REAL:
                            column.setType("Float");
                            //fields[i][1] = "Float";
                            break;
                        case Types.DOUBLE:
                            column.setType("Double");
                            //fields[i][1] = "Double";
                            break;
                        case Types.DATE:
                            column.setType("Date");
                            //fields[i][1] = "Date";
                            break;
                        case Types.TIMESTAMP:

                            column.setType("Timestamp");
                            //fields[i][1] = "Timestamp";
                            break;
                        case Types.DECIMAL:
                            column.setType("BigDecimal");
                            //fields[i][1]="BigDecimal";
                            break;
                        case Types.BLOB:
                        case Types.LONGVARBINARY:
                        case Types.BINARY:
                        case Types.VARBINARY:

                            column.setType("byte[]");
                            break;
                        default:
                            column.setType("String");
                            //fields[i][1] = "String";
                            break;
                    }
                    String columnName = metaData.getColumnLabel(i + 1);
                    column.setColumnName(columnName);
                    column.setColumnAlias(columnName);
                    //fields[i][2] = columnName;

                    //对列名进行驼峰处理，转变成为属性名称
                    column.setPropertyName(StringUtils.convertColNameToHumpStyle(columnName));
                    //fields[i][3] = StringUtils.convertColNameToHumpStyle(columnName);


                    column.setRemark("");
                    //fields[i][4] = "";
                    ResultSet rs2 = conn.getMetaData().getColumns(null, null, metaData.getTableName(i + 1),
                            metaData.getColumnName(i + 1));
                    if (rs2.next()) {
                        String tmp = rs2.getString("REMARKS");
                        if (tmp != null) {
                            column.setRemark(tmp);
                            //fields[i][4] = tmp;
                        }
                        if ("YES".equals(rs2.getString("IS_AUTOINCREMENT"))) {
                            column.setAutoIncreasement(true);
                            //fields[i][6]="Y";
                        } else {
                            column.setAutoIncreasement(false);
                            //fields[i][6]="N";
                        }
                    }

                    rs2.close();

                    column.setPrimaryKey(false);
                    table.addColumn(column);


                    //fields[i][5]="N";
                    //fields[i][6]="N";

                }

                //获取表的主键以及外键
                DatabaseMetaData databaseMetaData = conn.getMetaData();
                String catalog = conn.getCatalog();

                ResultSet primaryKeyResultSet = databaseMetaData.getPrimaryKeys(catalog, null, tableName);

                Set<String> primaryColumnName = new HashSet<>();

                while (primaryKeyResultSet.next()) {
                    String columnName = primaryKeyResultSet.getString("COLUMN_NAME");
                    //primaryColumnName.add(primaryKeyResultSet.getString("COLUMN_NAME"));
                    Column column = table.getColumnByColumnName(columnName);
                    if (column != null) {
                        column.setPrimaryKey(true);
                    }


                }

                //遍历所有列设置是否为主键的标识
//				for( int i = 0; i < columnCount; ++i){
//					if(primaryColumnName.contains(fields[i][2])){
//						fields[i][5]="Y";
//					}
//
//				}


                //获取所有的外键
                ResultSet foreignKeyResultSet = databaseMetaData.getImportedKeys(catalog, null, tableName);
                while (foreignKeyResultSet.next()) {
                    String fkColumnName = foreignKeyResultSet.getString("FKCOLUMN_NAME");
                    String pkTablenName = foreignKeyResultSet.getString("PKTABLE_NAME");
                    String pkColumnName = foreignKeyResultSet.getString("PKCOLUMN_NAME");

                    Table pkTable = getForeignTableInfo(conn, pkTablenName);

                    ForeignKey foreignKey = new ForeignKey();
                    foreignKey.setFkColumnName(fkColumnName);
                    foreignKey.setPkColumnName(pkColumnName);
                    foreignKey.setPkTable(pkTable);
                    table.addForeignKey(foreignKey);
                }

                rs.close();

                //获取上一次的设置
                Table savedTable = getSavedSetting(conn, tableName);
                if (savedTable != null) {
                    //表的别名
                    table.setTableAlias(savedTable.getTableAlias());
                    table.setSecondTableAlias(savedTable.getSecondTableAlias());

                    //设置外键的属性
                    if (savedTable.getForeignKeys() != null) {
                        Map<String, ForeignKey> foreignKeyMap = new HashMap<String, ForeignKey>();

                        //上一次选中的外键以及外键表的别名
                        for (ForeignKey foreignKey : savedTable.getForeignKeys()) {
                            foreignKeyMap.put(foreignKey.getFkColumnName(), foreignKey);
                        }

                        if (table.getForeignKeys() != null) {
                            for (ForeignKey foreignKey : table.getForeignKeys()) {
                                ForeignKey savedForeignKey = foreignKeyMap.get(foreignKey.getFkColumnName());
                                if (savedForeignKey != null) {
                                    Table savedPkTable = savedForeignKey.getPkTable();
                                    Table pkTable = foreignKey.getPkTable();
                                    if (pkTable != null && savedPkTable != null) {
                                        pkTable.setTableAlias(savedPkTable.getTableAlias());
                                        //设置选中的列
                                        for (Column savedColumn : savedPkTable.getColumns()) {
                                            Column column = pkTable.getColumnByColumnName(savedColumn.getColumnName());
                                            column.setColumnAlias(savedColumn.getColumnAlias());
                                            column.setPropertyName(savedColumn.getPropertyName());
                                            column.setForeignColumnSelected(true);
                                        }


                                    }
                                }
                            }
                        }


                    }

                }


                new OneKeyTableSqlBeanDialog(frame, table).setVisible(true);
            } catch (SQLException | ClassNotFoundException e1) {
                e1.printStackTrace();
                JOptionPane.showMessageDialog(frame, resourceBuddle.getString("DBException") + ":" + e1.getMessage());
            } finally {
                try {
                    if (conn != null)
                        conn.close();
                } catch (SQLException e1) {
                    e1.printStackTrace();
                }
            }
        } else {
            JOptionPane.showMessageDialog(frame, "请输入表名!");
        }
    }


    private Table getSavedSetting(Connection conn, String tableName) {

        try {

            String sql = "CREATE TABLE  if not exists  `tbl_code_generator_setting` (" +
                    "  `table_name` varchar(100) NOT NULL," +
                    "  `data` longblob NOT NULL," +
                    "  PRIMARY KEY (`table_name`)" +
                    ")";

            Statement statement = conn.createStatement();
            statement.executeUpdate(sql);


            sql = "select table_name,data from tbl_code_generator_setting where `table_name` = ? ";
            PreparedStatement preparedStatement = conn.prepareStatement(sql);
            preparedStatement.setString(1, tableName);
            ResultSet resultSet = preparedStatement.executeQuery();
            if (resultSet.next()) {

                //Blob blob = resultSet.getBlob(1);

                //反序列化
                byte[] data = resultSet.getBytes(SavedTableSetting.COLUMN_DATA);

                Table savedTable = (Table) SerializeUtil.readObject(data);

                return savedTable;


            } else {
                return null;
            }


        } catch (Throwable t) {

            t.printStackTrace();
            throw new RuntimeException(t);
        }
    }

    private Table getForeignTableInfo(Connection conn, String tableName) {


        try {
            String sql = "select * from " + tableName + " where 1=2 ";
            Table table = new Table();
            table.setTableName(tableName);
            ResultSet rs = conn.createStatement().executeQuery(sql);
            ResultSetMetaData metaData = rs.getMetaData();
            int columnCount = metaData.getColumnCount();
            for (int i = 0; i < columnCount; i++) {
                Column column = new Column();
                column.setDecorator("private");

                int type = metaData.getColumnType(i + 1);
                switch (type) {
                    case Types.INTEGER:
                    case Types.SMALLINT:
                    case Types.TINYINT:
                        column.setType("Integer");
                        break;
                    case Types.BIT:
                    case Types.BOOLEAN:
                        column.setType("Boolean");

                        break;
                    case Types.FLOAT:
                    case Types.REAL:
                        column.setType("Float");

                        break;
                    case Types.DOUBLE:
                        column.setType("Double");

                        break;
                    case Types.DATE:
                    case Types.TIMESTAMP:
                        column.setType("Timestamp");

                        break;
                    case Types.DECIMAL:
                        column.setType("BigDecimal");

                        break;
                    case Types.BLOB:
                        column.setType("Byte[]");
                        break;
                    default:
                        column.setType("String");

                        break;
                }
                String columnName = metaData.getColumnLabel(i + 1);
                column.setColumnName(columnName);
                column.setColumnAlias(columnName);


                //对列名进行驼峰处理，转变成为属性名称
                column.setPropertyName(StringUtils.convertColNameToHumpStyle(columnName));


                column.setRemark("");

//				ResultSet rs2 = conn.getMetaData().getColumns(null, null, metaData.getTableName(i + 1),
//						metaData.getColumnName(i + 1));
//				if (rs2.next()) {
//					String tmp = rs2.getString("REMARKS");
//					if (tmp != null){
//						column.setRemark(tmp);
//
//					}
//					if("YES".equals(rs2.getString("IS_AUTOINCREMENT"))){
//						column.setAutoIncreasement(true);
//
//					}
//					else{
//						column.setAutoIncreasement(false);
//
//					}
//				}
//
//				rs2.close();

                column.setAutoIncreasement(false);
                column.setPrimaryKey(false);
                table.addColumn(column);
            }
            return table;

        } catch (Throwable t) {
            throw new RuntimeException(t);
        }

    }

}
